// cf-659g
// 题意：给定n(<=10^6)个单位长度相邻从左到右高度分别是hi的木条组成的围栏，
//       现在要将其修成好看的，修的要求是每个围栏只能从上往下连续的减去
//       一些高度，不能减光，然后相邻的围栏剪掉部分必需至少有一条公共边。
//       问有多少种减的方案。
//
// 题解：我是用dp[i][h]来思考，表示前i个，第i个从上往下修到高度h的方案，
//       很容易知道它是sigma(dp[i-1][j]) 1<=j<=H，至少要有一条边共边。
//       如果当前木条高度比前一个大那直接求和就好，不然前一条选的高度要受
//       当前木条长度限制，我用另一个递推来维护这个限制，g[i]表示地i个木条
//       除去只减自己以外，每个高度前面相邻的方案。然后就可以O(n)维护了。
//
//       题解上是用calc(l, r)表示[l, r]这段区间都有减的方案数，就是高度最小值
//       的乘积，然后用前缀和来维护。也是O(n)。
//
// run: $exec < bfdiff.in
#include <iostream>

long long const mo = 1000000007;
int const maxn = 1000007;
long long h[maxn];
long long f[maxn];
long long g[maxn];
int n;

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n;
	for (int i = 1; i <= n; i++) std::cin >> h[i];
	long long ans = 0;
	for (int i = 1; i <= n; i++) {
		if (h[i] >= h[i - 1]) {
			f[i] = ((h[i - 1] - 1) * f[i - 1] + h[i] - 1) % mo;
			g[i] = (f[i - 1]) % mo;
		} else {
			long long t = h[i] - 1;
			if (i > 2) t = std::min(t, h[i - 2] - 1);
			f[i] = (((((h[i] - 1) * (((g[i - 1] * t) % mo) + h[i] - 1)) % mo) % mo) + h[i] - 1) % mo;
			g[i] = (((g[i - 1] * t) % mo) + h[i] - 1) % mo;
		}
		ans = (ans + f[i]) % mo;
	}
//	for (int i = 1; i <= n; i++) std::cout << f[i] << ' '; std::cout << '\n';
//	for (int i = 1; i <= n; i++) std::cout << g[i] << ' '; std::cout << '\n';

	std::cout << ans << '\n';
}

